﻿using System.Collections.Generic;
using System.Linq;

namespace VPLink2014.Data.MesApplis
{
	public class VODirectionMapper : VOTeamMapper
	{
		public VODirection direction;
		public VODirectionMapper()
			: base()
		{
		}
		public VODirectionMapper( string name ):base()
		{
            using (VPLinkLogConnection db = new VPLinkLogConnection())
			{
				direction = ( from u in db.VplinkEntities.Directions
							  where u.nom == name
							  select new VODirection() { Id = u.id, Name = u.nom } ).FirstOrDefault();
			}
		}

		public override void SetApplications( List<VOApplication> applications )
		{
            using (VPLinkLogConnection db = new VPLinkLogConnection())
			{
				Direction directionDb = ( from Direction dir in db.VplinkEntities.Directions
										   where dir.id == direction.Id
										   select dir ).FirstOrDefault<Direction>();

				// Deleted Apps
				List<AppliDirection> deletedApps = directionDb.AppliDirections.Where( i => !applications.Select( x => x.Id ).Contains( i.appli ) ).ToList<AppliDirection>();
                deletedApps.ForEach(x => db.VplinkEntities.AppliDirections.Remove(x));
				//Delete from users Db

				List<User> usersWithApplisFromServiceDb = ( from User usr in db.VplinkEntities.Users
															 from AppliUser appliUser in db.VplinkEntities.AppliUsers
															 where usr.Direction == this.direction.Name
															 where usr.Departement == ""
															 where usr.Service == ""
															 where usr.LoginUser == appliUser.user
															 select usr ).Distinct().ToList<User>();
				foreach( User user in usersWithApplisFromServiceDb )
				{
					List<AppliUser> specificUserApps = user.AppliUsers
						.Where( i => !applications.Select( x => x.Id ).Contains( i.appli ) )
						.OrderBy( x => x.rang ).ToList<AppliUser>();
					for( int i = 0; i < specificUserApps.Count(); i++ )
					{
						specificUserApps[i].rang = applications.Count() + i + 1;
					}
					if( deletedApps.Count() > 0 )
					{
						List<AppliUser> deletedUserApps = user.AppliUsers.Where( i => deletedApps.Select( x => x.appli ).Contains( i.appli ) ).ToList<AppliUser>();
                        deletedUserApps.ForEach(x => db.VplinkEntities.AppliUsers.Remove(x));
					}
				}
				foreach( VOApplication application in applications )
				{
					Application appliDb = ( from Application appli in db.VplinkEntities.Applications
											 where appli.id == application.Id
											 select appli ).FirstOrDefault<Application>();

					UpdateUsers( db, usersWithApplisFromServiceDb, application, appliDb );
					UpdateTeamApplis( db, directionDb, application, appliDb );
				}
			}
		}

		private void UpdateTeamApplis( VPLinkLogConnection db, Direction directionDb, VOApplication application, Application appliDb )
		{
			AppliDirection appliDepts = ( from AppliDirection dirs in db.VplinkEntities.AppliDirections
									 where dirs.direction == direction.Id
									 where dirs.appli == application.Id
									 select dirs ).FirstOrDefault<AppliDirection>();
			// Add New
			if( appliDepts == null )
			{
				AppliDirection newAppliDept = new AppliDirection()
				{
					Direction1 = directionDb,
					Application = appliDb,
					direction = this.direction.Id,
					appli = application.Id,
					rang = application.Rang,
					obligatoire = application.Obligatoire
				};
				db.VplinkEntities.AppliDirections.Add( newAppliDept );
			}
			else
			{
				// Update existing
				appliDepts.obligatoire = application.Obligatoire;
				appliDepts.rang = application.Rang;
			}
		}

        private static void UpdateUsers(VPLinkLogConnection db, List<User> usersWithApplisFromServiceDb, VOApplication application, Application appliDb)
		{
			foreach( User user in usersWithApplisFromServiceDb )
			{
				AppliUser appliUser = ( from AppliUser usrAppli in db.VplinkEntities.AppliUsers
										where usrAppli.appli == application.Id
										where usrAppli.user == user.LoginUser
										select usrAppli ).FirstOrDefault();

				if( appliUser == null )
				{
					db.VplinkEntities.AppliUsers.Add( new AppliUser()
					{
						appli = application.Id,
						user = user.LoginUser,
						User1 = user,
						Application = appliDb,
						obligatoire = application.Obligatoire,
						rang = application.Rang
					} );
				}
				else
				{
					appliUser.obligatoire = application.Obligatoire;
					appliUser.rang = application.Rang;
				}
			}
		}

		public override List<VOApplication> GetApplicationsTeam()
		{
			List<VOApplication> applicationsByDirection = new List<VOApplication>();
            using (VPLinkLogConnection db = new VPLinkLogConnection())
			{
				applicationsByDirection = (
									from appliDir in db.VplinkEntities.AppliDirections
									from applis in db.VplinkEntities.Applications
									from dirs in db.VplinkEntities.Directions
									where dirs.nom == this.direction.Name
									where applis.id == appliDir.appli
									where dirs.id == appliDir.direction
									orderby appliDir.rang
									select new VOApplication() { 
										Id = applis.id, 
										Url = applis.url, 
										Name = applis.titre, 
										Categorie = string.IsNullOrEmpty( applis.categorie ) ? "Autre" : applis.categorie, 
										Description = applis.description, 
										Obligatoire = appliDir.obligatoire, 
										Rang = appliDir.rang 
									} ).ToList<VOApplication>();
			}
			return applicationsByDirection;
		}
	}
}
